home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / dialupip / dialupip2.0 / src / diald / readconfig.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-11  |  11.1 KB  |  471 lines

  1. /*
  2. **  Copyright (c) 1991 Bolt Beranek and Newman, Inc.
  3. **  All rights reserved.
  4. **
  5. **  Redistribution and use in source and binary forms are permitted
  6. **  provided that: (1) source distributions retain this entire copyright
  7. **  notice and comment, and (2) distributions including binaries display
  8. **  the following acknowledgement:  ``This product includes software
  9. **  developed by Bolt Beranek and Newman, Inc. and CREN/CSNET'' in the
  10. **  documentation or other materials provided with the distribution and in
  11. **  all advertising materials mentioning features or use of this software.
  12. **  Neither the name of Bolt Beranek and Newman nor CREN/CSNET may be used
  13. **  to endorse or promote products derived from this software without
  14. **  specific prior written permission.
  15. **
  16. **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  17. **  WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  18. **  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19. */
  20. #include <stdio.h>
  21. #include <ctype.h>
  22. #include <netdb.h>
  23. #include <sgtty.h>
  24. #include <sys/types.h>
  25. #include <sys/param.h>
  26. #include <netinet/in_systm.h>
  27. #include <netinet/in.h>
  28. #include <netinet/ip.h>
  29. #include <arpa/inet.h>
  30. #include "dialupip.h"
  31. #include "diald.h"
  32.  
  33.  
  34. /*
  35. **  Some systems don't have these in their <netinet/in.h>
  36. */
  37. #ifndef    IPPROTO_EGP
  38. #define IPPROTO_EGP    8
  39. #endif    /* IPPROTO_EGP */
  40. #ifndef    IPPROTO_RDP
  41. #define IPPROTO_RDP    27
  42. #endif    /* IPPROTO_EGP */
  43.  
  44.  
  45. #define EQ(a, b)    (strcmp((a), (b)) == 0)
  46. #define nexttok()    strtok((char *)NULL, SEPARATORS)
  47.  
  48.  
  49. static int        errorcount;
  50. static int        linenum;
  51. static char        SEPARATORS[] = " \t";
  52. static REMOTE        *RemoteTable;
  53. static int        RemoteCount;
  54. static char        WHERE[] = "readconfig";
  55.  
  56.  
  57. /*
  58. **  Find this interface in our list.
  59. */
  60. REMOTE *
  61. findconfig(device)
  62.     register char    *device;
  63. {
  64.     register REMOTE    *rp;
  65.     register int    i;
  66.  
  67.     for (rp = RemoteTable, i = RemoteCount; --i >= 0; rp++)
  68.     if (strcmp(device, rp->Device) == 0)
  69.         return rp;
  70.     return NULL;
  71. }
  72.  
  73.  
  74. /*
  75. **  Is the host (or its network) on the list of hosts and networks?
  76. */
  77. int
  78. hostinlist(list, addr)
  79.     struct in_addr    *list;
  80.     struct in_addr    addr;
  81. {
  82.     register int    i;
  83.     register int    j;
  84.  
  85.     j = i = addr.s_addr % MAXHOSTS;
  86.  
  87.     do {
  88.     if (list[j].s_addr == 0)
  89.         return 0;
  90.     if (list[j].s_addr == addr.s_addr)
  91.         return 1;
  92.     if (inet_lnaof(list[j].s_addr) == 0
  93.      && inet_netof(list[j].s_addr) == inet_netof(addr.s_addr))
  94.         return 1;
  95.  
  96.     if (++j == MAXHOSTS)
  97.         j = 0;
  98.     } while (j != i);
  99.  
  100.     return 0;
  101. }
  102.  
  103.  
  104.  
  105. static void
  106. yyerror(path, fmt, arg)
  107.     char    *path;
  108.     char    *fmt;
  109.     char    *arg;
  110. {
  111.     char    buff[256];
  112.  
  113.     (void)sprintf(buff, "Error near line %d of\n\t \"%s\":  %s\n",
  114.     linenum, path, fmt);
  115.     d_log(DLOG_GENERAL, WHERE, buff, arg);
  116.     errorcount++;
  117. }
  118.  
  119.  
  120. static void
  121. parseprotocols(path, lp)
  122.     char    *path;
  123.     u_long    *lp;
  124. {
  125.     char    *p;
  126.     int        i;
  127.  
  128.     while (p = nexttok()) {
  129.     if (EQ(p, "tcp"))
  130.         i = IPPROTO_TCP;
  131.     else if (EQ(p, "rdp"))
  132.         i = IPPROTO_RDP;
  133.     else if (EQ(p, "egp"))
  134.         i = IPPROTO_EGP;
  135.     else if (EQ(p, "icmp"))
  136.         i = IPPROTO_ICMP;
  137.     else if (EQ(p, "udp"))
  138.         i = IPPROTO_UDP;
  139.     else if (EQ(p, "ggp"))
  140.         i = IPPROTO_GGP;
  141.     else {
  142.         yyerror(path, "Bad protocol \"%s\"", p);
  143.         continue;
  144.     }
  145.     lp[P_WORD(i)] |= P_BIT(i);
  146.     }
  147. }
  148.  
  149.  
  150. static int
  151. positivenumber(p)
  152.     char    *p;
  153. {
  154.     if (*p == '\0')
  155.     return 0;
  156.     for ( ; *p; p++)
  157.     if (!isdigit(*p))
  158.         return 0;
  159.     return 1;
  160. }
  161.  
  162.  
  163. static long
  164. parsetime(path)
  165.     char    *path;
  166. {
  167.     long    l;
  168.     int        i;
  169.     char    *p;
  170.  
  171.     for (l = 0; p = nexttok(); )
  172.     if (!positivenumber(p) || (i = atoi(p)) < 0 || i > 23)
  173.         yyerror(path, "Bad hour \"%s\"", p);
  174.     else
  175.         l |= (1L << i);
  176.     return l;
  177. }
  178.  
  179.  
  180. static int
  181. addhosttolist(list, addr)
  182.     struct in_addr    *list;
  183.     struct in_addr    addr;
  184. {
  185.     register int    i;
  186.     register int    j;
  187.  
  188.     j = i = addr.s_addr % MAXHOSTS;
  189.     do {
  190.     if (list[j].s_addr == 0) {
  191.         list[j] = addr;
  192.         return 1;
  193.     }
  194.     if (++j == MAXHOSTS)
  195.         j = 0;
  196.     } while (j != i);
  197.  
  198.     return 0;
  199. }
  200.  
  201.  
  202.  
  203. static int
  204. parseaddresslist(path, list)
  205.     char        *path;
  206.     struct in_addr    *list;
  207. {
  208.     char        *p;
  209.     struct in_addr    new;
  210.     int            i;
  211.     struct hostent    *hp;
  212.     struct netent    *np;
  213.  
  214.     for (i = 0; p = nexttok(); i++) {
  215.     if ((new.s_addr = inet_addr(p)) != -1)
  216.         ;
  217.     else if (np = getnetbyname(p))
  218.         new = inet_makeaddr(np->n_net, 0);
  219.     else if (hp = gethostbyname(p))
  220.         bcopy(hp->h_addr, (caddr_t)&new, sizeof new);
  221.     else {
  222.         yyerror(path, "Bad IP address \"%s\"", p);
  223.         continue;
  224.     }
  225.     if (!hostinlist(list, new) && !addhosttolist(list, new))
  226.         yyerror(path, "Can't add \"%s\" to address list", p);
  227.     }
  228.     return i;
  229. }
  230.  
  231.  
  232. static int
  233. readentry(path, rp, line)
  234.     char        *path;
  235.     REMOTE        *rp;
  236.     char        *line;
  237. {
  238.     static char        MISSINGFIELD[] = "Required \"%s\" field is missing";
  239.     FILE        *F;
  240.     char        *sitep;
  241.     char        *ttysp;
  242.     char        *scriptp;
  243.     char        *transp;
  244.     char        *accessp;
  245.     char        *word;
  246.     char        *p;
  247.     char        *fp;
  248.     char        buff[BUFSIZ];
  249.     int            i;
  250.  
  251.     /* Make sure we have six colon-separated fields. */
  252.     if ((sitep = strchr(line, ':')) == NULL
  253.      || (ttysp = strchr(sitep + 1, ':')) == NULL
  254.      || (scriptp = strchr(ttysp + 1, ':')) == NULL
  255.      || (transp = strchr(scriptp + 1, ':')) == NULL
  256.      || (accessp = strchr(transp + 1, ':')) == NULL) {
  257.     yyerror(path, "Too few fields", (char *)NULL);
  258.     return 0;
  259.     }
  260.     *sitep++ = '\0';
  261.     *ttysp++ = '\0';
  262.     *scriptp++ = '\0';
  263.     *transp++ = '\0';
  264.     *accessp++ = '\0';
  265.  
  266.     /* Field one, the interface. */
  267.     if (*line == '\0') {
  268.     yyerror(path, MISSINGFIELD, "interface");
  269.     return 0;
  270.     }
  271.     (void)strcpy(rp->Device, line);
  272.  
  273.     /* Field two, the site name. */
  274.     if (*sitep == '\0') {
  275.     yyerror(path, MISSINGFIELD, "site");
  276.     return 0;
  277.     }
  278.     (void)strcpy(rp->Sitename, sitep);
  279.  
  280.     /* Field three, the tty#baudrate entries. */
  281.     if (*ttysp == '\0' || (p = strtok(ttysp, SEPARATORS)) == NULL) {
  282.     yyerror(path, MISSINGFIELD, "ttys");
  283.     return 0;
  284.     }
  285.     for (i = 0; p && i < MAXDEVICES; i++, p = nexttok()) {
  286.     if ((fp = strchr(p, '#')) == NULL)
  287.         rp->Speeds[i] = -1;
  288.     else
  289.         *fp++ = '\0';
  290.     (void)strcpy(rp->Lines[i], p);
  291.     if (fp)
  292.         switch (atoi(fp)) {
  293.         default:
  294.         yyerror(path, "Bad speed \"%s\"\n", fp);
  295.         break;
  296.         case 1200:    rp->Speeds[i] = B1200;    break;
  297.         case 2400:    rp->Speeds[i] = B2400;    break;
  298.         case 4800:    rp->Speeds[i] = B4800;    break;
  299.         case 9600:    rp->Speeds[i] = B9600;    break;
  300.         case 19200:    rp->Speeds[i] = EXTA;    break;
  301.         case 38400:    rp->Speeds[i] = EXTB;    break;
  302.         }
  303.     }
  304.     if (i >= MAXDEVICES) {
  305.     yyerror(path, "Too many tty entries", (char *)NULL);
  306.     return 0;
  307.     }
  308.     while (i < MAXDEVICES)
  309.     rp->Lines[i++][0] = '\0';
  310.  
  311.     /* Field four, the script file and parameters. */
  312.     if (*scriptp == '\0' || (p = strtok(scriptp, SEPARATORS)) == NULL) {
  313.     yyerror(path, "Missing script name", (char *)NULL);
  314.     return 0;
  315.     }
  316.     if (*p == '/')
  317.     (void)strcpy(rp->Script, p);
  318.     else
  319.     (void)sprintf(rp->Script, "%s/%s", CONFIG_DIR, p);
  320.     for (fp = rp->FieldData, i = 0; i < 10 && (p = nexttok()); i++) {
  321.     if (fp > &rp->FieldData[sizeof rp->FieldData - 1]) {
  322.         yyerror(path, "Parameters too long", (char *)NULL);
  323.         break;
  324.     }
  325.     rp->Fields[i] = fp - rp->FieldData;
  326.     fp += strlen(strcpy(fp, p));
  327.     *fp++ = '\0';
  328.     }
  329.     if (i >= 10) {
  330.     yyerror(path, "Too many parameters", (char *)NULL);
  331.     return 0;
  332.     }
  333.     rp->FieldCount = i;
  334.  
  335.     /* Field five, the transcript file. */
  336.     if ((p = strchr(transp, '@')) && isdigit(p[1]) && p[2] == '\0')
  337.     rp->Transtyle = *++p == '0' ? TS_LOW : TS_HIGH;
  338.     else
  339.     rp->Transtyle = TS_LOW;
  340.     if (*transp == '/')
  341.     (void)strcpy(rp->Transcript, transp);
  342.     else
  343.     (void)sprintf(rp->Transcript, "%s/%s", CONFIG_DIR, transp);
  344.  
  345.     /* Set access defaults. */
  346.     for (i = 0; i < 7; i++)
  347.     rp->Times[i] = ~0;
  348.     for (i = 0; i < 8; i++)
  349.     rp->Protocols[i] = ~0;
  350.     for (rp->AllowCount = 0, i = 0; i < MAXHOSTS; i++)
  351.     rp->AllowTo[i].s_addr = 0;
  352.     for (rp->DisallowCount = 0, i = 0; i < MAXHOSTS; i++)
  353.     rp->DisallowFrom[i].s_addr = 0;
  354.     rp->Inactivity = INACT_UNDEF;
  355.  
  356.     /* Field five, the access file. */
  357.     if (*accessp == '\0')
  358.     return errorcount == 0;
  359.  
  360.     if (*accessp == '/')
  361.     (void)strcpy(buff, accessp);
  362.     else
  363.     (void)sprintf(buff, "%s/%s", CONFIG_DIR, accessp);
  364.     if ((F = fopen(buff, "r")) == NULL) {
  365.     yyerror(path, "Can't open access file \"%s\"", accessp);
  366.     return 0;
  367.     }
  368.  
  369.     /* Read lines. */
  370.     for (linenum = 1; fgets(buff, sizeof buff, F); linenum++) {
  371.     if ((p = strchr(buff, '\n')) == NULL) {
  372.         yyerror(buff, "Line too long", (char *)NULL);
  373.         (void)fclose(F);
  374.         return 0;
  375.     }
  376.     *p = '\0';
  377.     if (*p == '\0' || *p == '#')
  378.         continue;
  379.     if ((word = strtok(buff, SEPARATORS)) == NULL)
  380.         continue;
  381.     /* Dispatch on the word to fill in the fields. */
  382.     if (EQ(word, "allowto") || EQ(word, "gooddstaddresses"))
  383.         rp->AllowCount += parseaddresslist(path, rp->AllowTo);
  384.     else if (EQ(word, "disallowfrom") || EQ(word, "badsrcaddresses"))
  385.         rp->DisallowCount += parseaddresslist(path, rp->DisallowFrom);
  386.     else if (EQ(word, "protocols"))
  387.         parseprotocols(path, rp->Protocols);
  388.     else if (EQ(word, "inactivity")) {
  389.         if (p = nexttok())
  390.         if (!positivenumber(p))
  391.             yyerror(accessp, "Bad number \"%s\"", p);
  392.         else
  393.             rp->Inactivity = atoi(p);
  394.     }
  395.     else if (EQ(word, "weekdays"))
  396.         rp->Times[1] = rp->Times[2] = rp->Times[3] =
  397.         rp->Times[4] = rp->Times[5] = parsetime(path);
  398.     else if (EQ(word, "weekends"))
  399.         rp->Times[0] = rp->Times[6] = parsetime(path);
  400.     else if (EQ(word, "sun") || EQ(word, "sunday"))
  401.         rp->Times[0] = parsetime(path);
  402.     else if (EQ(word, "mon") || EQ(word, "monday"))
  403.         rp->Times[1] = parsetime(path);
  404.     else if (EQ(word, "tue") || EQ(word, "tuesday"))
  405.         rp->Times[2] = parsetime(path);
  406.     else if (EQ(word, "wed") || EQ(word, "wednesday"))
  407.         rp->Times[3] = parsetime(path);
  408.     else if (EQ(word, "thu") || EQ(word, "thursday"))
  409.         rp->Times[4] = parsetime(path);
  410.     else if (EQ(word, "fri") || EQ(word, "friday"))
  411.         rp->Times[5] = parsetime(path);
  412.     else if (EQ(word, "sat") || EQ(word, "saturday"))
  413.         rp->Times[6] = parsetime(path);
  414.     else
  415.         yyerror(accessp, "Bad parameter \"%s\"", word);
  416.     }
  417.  
  418.     (void)fclose(F);
  419.     return errorcount == 0;
  420. }
  421.  
  422.  
  423. int
  424. readconfig(path)
  425.     char        *path;
  426. {
  427.     FILE        *F;
  428.     char        *p;
  429.     char        buff[BUFSIZ];
  430.     int            i;
  431.  
  432.     /* Count the number of lines in the file. */
  433.     linenum = 0;
  434.     if ((F = fopen(path, "r")) == NULL) {
  435.     yyerror(path, "Can't open for reading, %m", (char *)NULL);
  436.     return 0;
  437.     }
  438.     while (fgets(buff, sizeof buff, F))
  439.     if (buff[0] != '#')
  440.         linenum++;
  441.     rewind(F);
  442.  
  443.     /* Allocate space for the table. */
  444.     if (RemoteTable)
  445.     free((char *)RemoteTable);
  446.     RemoteTable = (REMOTE *)malloc((unsigned int)linenum * sizeof (REMOTE));
  447.     if (RemoteTable == NULL) {
  448.     yyerror(path, "Can't allocate table, %m", (char *)NULL);
  449.     return 0;
  450.     }
  451.  
  452.     errorcount = 0;
  453.     for (i = 1, RemoteCount = 0; fgets(buff, sizeof buff, F); i++) {
  454.     if ((p = strchr(buff, '\n')) == NULL) {
  455.         yyerror(path, "Line too long", (char *)NULL);
  456.         (void)fclose(F);
  457.         return 0;
  458.     }
  459.     *p = '\0';
  460.     if (buff[0] == '#' || buff[0] == '\0')
  461.         continue;
  462.  
  463.     linenum = i;
  464.     if (readentry(path, &RemoteTable[RemoteCount], buff))
  465.         RemoteCount++;
  466.     }
  467.  
  468.     (void)fclose(F);
  469.     return errorcount == 0;
  470. }
  471.